{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Java 接口\n",
    "接口（英文：Interface），在JAVA编程语言中是一个抽象类型，是抽象方法的集合，接口通常以interface来声明。一个类通过继承接口的方式，从而来继承接口的抽象方法。\n",
    "\n",
    "接口并不是类，编写接口的方式和类很相似，但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。\n",
    "\n",
    "除非实现接口的类是抽象类，否则该类要定义接口中的所有方法。\n",
    "\n",
    "接口无法被实例化，但是可以被实现。**一个实现接口的类，必须实现接口内所描述的所有方法，否则就必须声明为抽象类**。另外，在 Java 中，接口类型可用来声明一个变量，他们可以成为一个空指针，或是被绑定在一个以此接口实现的对象。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 接口与类相似点：\n",
    "- 一个接口可以有多个方法。\n",
    "- 接口文件保存在 .java 结尾的文件中，文件名使用接口名。\n",
    "- 接口的字节码文件保存在 .class 结尾的文件中。\n",
    "- 接口相应的字节码文件必须在与包名称相匹配的目录结构中。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 接口与类的区别：\n",
    "- 接口不能用于实例化对象。\n",
    "- 接口没有构造方法。\n",
    "- 接口中所有的方法必须是抽象方法。\n",
    "- 接口不能包含成员变量，除了 static 和 final 变量。\n",
    "- 接口不是被类继承了，而是要被类实现。\n",
    "- 接口支持多继承。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 接口特性\n",
    "- 接口是隐式抽象的，当声明一个接口的时候，不必使用abstract关键字。\n",
    "- 接口中的方法都是公有的。\n",
    "- 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 **public abstract**（只能是 public abstract，其他修饰符都会报错）。\n",
    "- 接口中可以含有变量，但是接口中的变量会被隐式的指定为 **public static final** 变量（并且只能是 public，用 private 修饰会报编译错误）。\n",
    "- 接口中的方法是不能在接口中实现的，只能由实现接口的类来实现接口中的方法。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 抽象类和接口的区别\n",
    "1. 抽象类中的方法可以有方法体，就是能实现方法的具体功能，但是接口中的方法不行。\n",
    "2. 抽象类中的成员变量可以是各种类型的，而接口中的成员变量只能是 public static final 类型的。\n",
    "3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法)，而抽象类是可以有静态代码块和静态方法。\n",
    "4. 一个类只能继承一个抽象类，而一个类却可以实现多个接口。\n",
    "\n",
    "**注：JDK 1.8 以后，接口里可以有静态方法和方法体了。**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 接口的声明\n",
    "接口的声明语法格式如下：\n",
    "```java\n",
    "[可见度] interface 接口名称 [extends 其他的接口名] {\n",
    "        // 声明变量\n",
    "        // 抽象方法\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 接口的实现\n",
    "当类实现接口的时候，类要实现接口中所有的方法。否则，类必须声明为抽象的类。\n",
    "\n",
    "类使用implements关键字实现接口。在类声明中，Implements关键字放在class声明后面。\n",
    "\n",
    "实现一个接口的语法，可以使用这个公式：\n",
    "\n",
    "Animal.java 文件代码：\n",
    "```java\n",
    "...implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "重写接口中声明的方法时，需要注意以下规则：\n",
    "\n",
    "- 类在实现接口的方法时，不能抛出强制性异常，只能在接口中，或者继承接口的抽象类中抛出该强制性异常。\n",
    "- 类在重写方法时要保持一致的方法名，并且应该保持相同或者相兼容的返回值类型。\n",
    "- 如果实现接口的类是抽象类，那么就没必要实现该接口的方法。\n",
    "\n",
    "在实现接口的时候，也要注意一些规则：\n",
    "- 一个类可以同时实现多个接口。\n",
    "- 一个类只能继承一个类，但是能实现多个接口。\n",
    "- 一个接口能继承另一个接口，这和类之间的继承比较相似。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 标记接口\n",
    "最常用的继承接口是没有包含任何方法的接口。\n",
    "\n",
    "标记接口是没有任何方法和属性的接口.它仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情。\n",
    "\n",
    "标记接口作用：简单形象的说就是给某个对象打个标（盖个戳），使对象拥有某个或某些特权。\n",
    "\n",
    "例如：java.awt.event 包中的 MouseListener 接口继承的 java.util.EventListener 接口定义如下：\n",
    "```java\n",
    "package java.util;\n",
    "public interface EventListener{}\n",
    "```\n",
    "没有任何方法的接口被称为标记接口。标记接口主要用于以下两种目的：\n",
    "\n",
    "- **建立一个公共的父接口：**\n",
    "正如EventListener接口，这是由几十个其他接口扩展的Java API，你可以使用一个标记接口来建立一组接口的父接口。例如：当一个接口继承了EventListener接口，Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。\n",
    "\n",
    "- **向一个类添加数据类型：**\n",
    "这种情况是标记接口最初的目的，实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法)，但是该类通过多态性变成一个接口类型。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Java",
   "language": "java",
   "name": "java"
  },
  "language_info": {
   "codemirror_mode": "java",
   "file_extension": ".jshell",
   "mimetype": "text/x-java-source",
   "name": "Java",
   "pygments_lexer": "java",
   "version": "11.0.8+10-post-Ubuntu-0ubuntu120.04"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
